<template>
  <div>
    <el-form ref="form" :model="form" :rules="rules">
      <el-form-item>
        <div style="text-align: center">
          <img id="srcRef" ref="srcRef" :src="src" alt=""/>
          <div id="nameRef" ref="nameRef" v-text="username"></div>
        </div>
<!--        <div style="color: red">* 在进行操作前请确保您已开启VPN并能正常访问Google</div>-->
        <div style="color: red">* 新版本无需挂载vpn</div>
        <!--<el-button type="primary" @click="initGapi2">获取Google授权</el-button>-->
        <!--<el-button type="primary" @click="authenticate">2.获取Google授权</el-button>-->
      </el-form-item>
      <el-form-item label="视频描述:">
        <el-input id="id-offer-componets-youtubedialong-description"
                  type="textarea" :disabled="uploadLoading" placeholder="Say something for these videos..."
                  v-model="form.description"/>
      </el-form-item>
      <!--<el-form-item label="观众限制:">
        <el-select v-model="form.audience">
          <el-option
            v-for="item in audienceOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>-->
      <el-form-item label="公开范围:">
        <el-select id="id-offer-componets-youtubedialong-privacyStatus"
                   v-model="form.privacyStatus" :disabled="uploadLoading">
          <el-option
            v-for="item in privacyOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="频道列表:" prop="refreshToken">
        <el-select id="id-offer-componets-youtubedialong-uploadLoading"
                   v-model="form.refreshToken" :disabled="uploadLoading" placeholder="请选择要上传的频道" required>
          <el-option
            v-for="item in channelList"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
<!--      <el-form-item label="请选择需要重新上传的素材">-->
<!--        <el-table :data="reUploadInfo" @selection-change="handleSelectUpload">-->
<!--          <el-table-column type="selection" align="center"></el-table-column>-->
<!--          <el-table-column>-->
<!--            <template slot-scope="{row}">-->
<!--              <el-image :src="row.thumbnailUrl"></el-image>-->
<!--            </template>-->
<!--          </el-table-column>-->
<!--          <el-table-column prop="name" label="名称"></el-table-column>-->
<!--          <el-table-column prop="youtubeLink" label="油管链接"></el-table-column>-->
<!--        </el-table>-->
<!--      </el-form-item>-->
<!--      <el-form-item>-->
<!--        <div style="margin: 0; padding: 0; text-align: center" v-show="uploadTotal > 0">-->
<!--          <el-steps align-center :active="uploadCurrent" finish-status="success">-->
<!--            <el-step v-for="n in uploadTotal" icon="el-icon-loading">-->
<!--              <template slot="description">-->
<!--                <progress :id="'upload-progress' + (n - 1)" max="1" value="0" style="width: 50%"></progress>-->
<!--                <span :id="'percent-transferred' + (n - 1)"> 0</span> %-->
<!--              </template>-->
<!--            </el-step>-->
<!--          </el-steps>-->
<!--          <span>正在上传第{{ (uploadCurrent + 1) >= uploadTotal ? uploadTotal : uploadCurrent + 1 }}个素材, 共{{-->
<!--              uploadTotal-->
<!--            }}个</span>-->
<!--          <div id="bytesPerSecond">上传速度: {{ bytesPerSecond + ' kb/s' }}</div>-->
<!--        </div>-->
<!--      </el-form-item>-->
      <el-form-item>
        <!--<el-button @click="initGapi">initGapi</el-button>-->
        <!--<el-button @click="initGapi2">initGapi2</el-button>-->
        <!--<el-button @click="loadClient">loadClient</el-button>-->
        <!--<el-button @click="getUserInfo">getUserInfo</el-button>-->
<!--        <el-button @click="getAccessToken" type="primary" :loading="uploadLoading">开始上传</el-button>-->
        <el-button @click="uploadYoutubeBackend" type="primary" :loading="uploadLoading">开始上传</el-button>
      </el-form-item>
    </el-form>
    <el-dialog
    :visible="showuploadYt"
    :modal-append-to-body="false"
    @close="closeUploadYT"
    >
      <div class="drawer__content">
        <div class="drawer__body">
          <el-table :data="uploadYtData" v-loading="uploadYtLoading">
            <el-table-column prop="name" label="名称"/>
            <el-table-column label="上传状态">
              <template slot-scope="{row}">
                <span>{{getStatusLable(row.status)}}</span>
              </template>
            </el-table-column>
          </el-table>
          <template>
            <el-progress :percentage="ytprogress" :format="getFormat"></el-progress>
          </template>
          <div v-show="youtubeProcessing"><i class="el-icon-loading"></i>上传中...</div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import '@/util/googleApis';
import {UploadVideo} from '@/util/upload_video';
import '@/util/cors_upload';
import {downloadCreative, uploadVideoToYoutube, getUploadToYTProgress} from '@/api/offer/creative';
import {exchangeToken, getChannelSelect} from "@/api/business/youtubeConfig";
import {queryVariableByKey, queryYoutubeQuotaLimit} from "@/api/system/client";

export default {
  name: "youtubeDialog",
  props: {
    creativeIds:{
      type:String
    },
    reUploadInfo:{
      type:Array,
    }
  },
  data() {
    return {
      formRules:{
        refreshToken: {required: true, message: "请选择频道", trigger: "change" }
      },
      youtubeProcessing:false,
      creativeCount: 0,
      maxLookup: 60,
      lookupStatus: 0,
      ytprogress: 0,
      uploadYtLoading:false,
      uploadYtData: [],
      reUploadSelection:[],
      uploadTTTimer:null,
      showuploadYt:false,
      privacyOptions: [
        {
          value: 'unlisted',
          label: '不公开列出'
        }, {
          value: 'public',
          label: '公开'
        }, {
          value: 'private',
          label: '私享'
        }
      ],
      audienceOptions: [
        {
          value: undefined,
          label: '无'
        }, {
          value: true,
          label: '是，内容是面向儿童的'
        }, {
          value: false,
          label: '否，内容不是面向儿童的'
        }
      ],
      ytStatus:[
        {
          label:"成功",
          value: 1
        },
        {
          label:"上传中",
          value: 0
        },
        {
          label:"失败",
          value: 2
        },
      ],
      channelList: [],
      form: {
        refreshToken: '',
        privacyStatus: 'unlisted',
        audience: undefined,
        description: ''
      },
      rules: {
        refreshToken: [{required: true, message: '请选择要上传的频道', trigger: 'change'}]
      },
      username: '',
      src: '',  // https://yt3.ggpht.com/ytc/AKedOLTiFyiEztsZNDUkfyFdVLT0FqZDF5kDlB_D9kNbWhOrbQ=s88-c-k-c0x00ffffff-no-rj
      scope: 'https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtube.upload',
      client: 'https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest',
      apiKey: 'AIzaSyDnQaprK9K4pwhbr5i7alrQ8-uxexA_xBk',
      clientId: '434175254256-f9ldue13rpgn7c6oa5n6s6qqsr5geoge.apps.googleusercontent.com',
      clientSecret: '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',
      grantType: 'refresh_token',
      accessToken: '',
      uploadVideo: null,
      authorization: true,
      uploadPercentage: 0,
      uploadCurrent: 0,
      uploadTotal: 0,
      completeCount: 0,
      youTubeCompleteCount: 0,
      youTubeErrorCount: 0,
      uploadLoading: false,
      bytesPerSecond: 0,
      // 获取token请求句柄，用于取消请求
      getAccessTokenXhr: null,
      // 获取上传请求句柄，用于取消请求
      uploadXhr: null
    }
  },
  mounted() {
    //this.initGapi2()
    this.getChannelDropdown()
  },
  beforeRouteLeave() {
    console.log("检测到离开")
  },
  methods: {
    handleSelectUpload(val){
      console.log("select ->", val)
      this.reUploadSelection = val
    },
    getFormat(){
      console.log("% ->", parseInt(this.ytprogress) + '%')
      return parseInt(this.ytprogress) + '%'
    },
    getQuotaLimit(){
      queryYoutubeQuotaLimit().then((res) => {
        if(typeof res.data.data === "boolean"){
          if(res.data.data){
            this.handleUploadYTStatus()
          } else {
            this.closeUploadYT("今天限额已满")
          }
        } else {
          this.$confirm('当前无法获取限额(限额满时,视频一定会上传失败), 是否继续尝试上传视频到Youtube?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.handleUploadYTStatus()
          }).catch(() => {
            this.closeUploadYT("已取消操作")
          })
        }
      }).catch((err) => {
        this.$confirm('当前无法获取限额(限额满时,视频一定会上传失败), 是否继续尝试上传视频到Youtube?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.handleUploadYTStatus()
        }).catch(() => {
          this.closeUploadYT("已取消操作")
        })
      })
    },
    getStatusLable(status){
      let sts = ""
      this.ytStatus.forEach(item => {
        if(item.value === parseInt(status)){
          sts =  item.label
          return sts
        }
      })
      return sts
    },
    TTTimerEnd(tmr) {
      clearInterval(tmr);
      tmr = null // 这里最好清除一下，回归默认值
      // 众所周知，定时器返回一个随机整数，用于表示定时器的编号，后面通过名字可以取消这个定时器的执行。
    },
    uploadYoutubeBackend(){
      this.$confirm("确定上传吗？", {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
        this.$refs["form"].validate((valid) => {
          if (valid) {
            if (!this.creativeIds) {
              this.$message.error("当前未选择素材!")
            } else {
              this.creativeCount = this.creativeIds.split(",").length
              this.uploadLoading = true
              this.$emit('updateTubeUploading', true)
              this.getQuotaLimit()
            }
          } else {
            return false;
          }
        });
      }).catch(() => {
        this.closeUploadYT("已取消操作")
      })
    },
    handleUploadYTStatus(){
      this.showuploadYt = true
      this.uploadYtLoading = true
      this.youtubeProcessing = true
      let params = {
        ...this.form,
        creativeIds:this.creativeIds
      }
      uploadVideoToYoutube(params).then(res => {
        if(res.data.data){
          this.uploadLoading = false
          this.getUploadYtStatus()
          this.uploadTTTimer = setInterval(() => {
            this.getUploadYtStatus()
          }, 5000)
        } else {
          this.closeUploadYT("服务器端申请上传youtube失败，请重试")
        }
      }).catch(err => {
        this.closeUploadYT(err)
      })
    },
    getUploadYtStatus(){
      getUploadToYTProgress({creativeIds:this.creativeIds})
        .then(res => {
          this.uploadYtLoading = false
          this.uploadYtData = res.data.data
          this.getProgress()
        }).finally(() => {
        if(this.ytprogress === 100){
          this.closeUploadYT("")
        }
        this.lookupStatus += 1
        if(this.lookupStatus >= this.maxLookup){
          this.closeUploadYT("已到达最大查看时间5分钟")
        }
      })
    },
    getProgress(){
      let done = 0
      this.youTubeCompleteCount = 0
      this.youTubeErrorCount = 0
      let cl = this.uploadYtData.length
      this.uploadYtData.forEach(item => {
        if(item.status !== 0){
          done += 1
          if(parseInt(item.status) === 1){
            this.youTubeCompleteCount += 1
          } else {
            this.youTubeErrorCount += 1
          }
        }
      })
      this.ytprogress = (done / cl) * 100
    },
    closeUploadYT(msg){
      this.showuploadYt = false
      this.TTTimerEnd(this.uploadTTTimer)
      this.youtubeProcessing = false
      this.uploadYtLoading = false
      this.lookupStatus = 0
      this.ytprogress = 0
      this.creativeIds = ""
      this.uploadYtData = []
      if(this.youTubeCompleteCount + this.youTubeErrorCount === this.creativeCount){
        this.validYouTubeStatus()
        let msg = "所有上传视频均已处理, 成功:" + this.youTubeCompleteCount + ",失败:" + this.youTubeErrorCount
        if(this.youTubeCompleteCount ===  this.creativeCount){
          this.$message.success(msg)
        } else if(this.youTubeErrorCount === this.creativeCount){
          this.$message.error(msg)
        } else {
          this.$message.warning(msg)
        }
      } else {
        if(msg !== undefined && msg !== "" && msg !== null){
          this.validYouTubeStatusFailed(msg)
        } else {
          this.validYouTubeStatusFailed("主动关闭")
        }
      }
    },
    handleCloseUploadYT(){
      this.showuploadYt = false
      this.TTTimerEnd(this.uploadTTTimer)
      this.youtubeProcessing = false
      this.uploadYtLoading = false
      this.lookupStatus = 0
      this.ytprogress = 0
      this.youTubeCompleteCount = 0
      this.youTubeErrorCount = 0
      this.creativeIds = ""
      this.uploadYtData = []
      this.validYouTubeStatusFailed()
      this.$message.warning("取消监测上传结果")
    },
    validYouTubeStatusFailed(msg){
      this.$emit('validYouTubeStatus', this.youTubeCompleteCount,
        this.creativeCount - this.youTubeCompleteCount, msg)
      this.creativeCount = 0
      this.youTubeCompleteCount = 0
      this.youTubeErrorCount = 0
    },
    initGapi2() {
      if (!gapi.auth2) {
        let self = this
        this.$message.success("正在初始化客户端，请确保当前网络可以访问Google，长时间不成功请刷新页面再重试")
        gapi.load("client:auth2", function () {
          gapi.auth2.init({client_id: self.clientId})
            .then(() => {
              self.$message.success("初始化完成!")
              self.authenticate()
            }, (err) => {
              console.log(err)
              self.$message.error("初始化失败，参考信息: " + JSON.stringify(err))
            }).catch(() => {
            self.$message.error("初始化失败，请确认您已开启VPN并刷新页面重试！")
          })
        })
      } else {
        this.authenticate()
      }
    },
    authenticate() {
      console.log(gapi.auth2)
      if (!gapi.auth2) {
        this.$message.error("Google客户端未初始化，请重试!")
      } else {
        return gapi.auth2.getAuthInstance().signIn({scope: this.scope})
          .then(() => {
            console.log("Sign-in successful")
            this.$message.success("登录成功, 正在获取授权信息。")
            this.loadClient()
          }, (err) => {
            console.log("Error signing in", err)
            if (err) {
              if (err.error !== "popup_closed_by_user") {
                this.$message.info("登陆未成功，参考信息: " + JSON.stringify(err))
              }
            }
          })
      }
    },
    loadClient() {
      console.log(gapi.client)
      if (!gapi.auth2) {
        this.$message.error("Google客户端正在初始化!")
      } else {
        gapi.client.setApiKey(this.apiKey);
        gapi.client.load(this.client)
          .then(() => {
            console.log("GAPI client loaded for API");
            this.getUserInfo()
          }, (err) => {
            console.error("Error loading GAPI client for API", err);
            this.$message.error("加载用户信息异常，参考信息: " + err)
          })
      }
    },
    getUserInfo() {
      if (!gapi.auth2) {
        this.$message.error("当前未获取Google授权!")
      } else {
        let user = gapi.auth2.getAuthInstance().currentUser.get();
        let oauthToken = user.getAuthResponse().access_token;
        this.uploadVideo = new UploadVideo();
        this.uploadVideo.ready(oauthToken, this);
      }
    },
    getChannelDropdown() {
      getChannelSelect().then(res => {
        this.channelList = res.data.data
      })
    },
    getAccessToken() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.uploadLoading = true
          let data = {
            client_id: this.clientId,
            client_secret: this.clientSecret,
            grant_type: this.grantType,
            refresh_token: this.form.refreshToken
          }
          exchangeToken(data, (res) => {
            console.log(res);
            let response = JSON.parse(res.currentTarget.response)
            this.accessToken = response.access_token
            if (this.accessToken) {
              this.upload()
            } else {
              this.$message.error("获取令牌失败，请联系管理员尝试在配置页面刷新授权")
              this.uploadLoading = false
            }
          }, (res) => {
            console.log(res);
            this.$message.error("获取令牌失败，请确认您已开启VPN并能正常访问Google")
            this.uploadLoading = false
          }, (xhr) => {
            this.getAccessTokenXhr = xhr
          })
        }
      })
    },
    async upload() {
      if (!this.creativeIds) {
        this.$message.error("当前未选择素材!")
      } else {
        this.uploadLoading = true
        this.$emit('updateTubeUploading', true)
        let idArray = this.creativeIds.split(',')
        let size = idArray.length
        this.uploadTotal = size
        this.uploadVideo = new UploadVideo();
        for (let i = 0; i < size; i++) {
          let param = {
            creativeId: idArray[i]
          }
          let uploadStartTime = Date.now(), lastLoaded = 0
          await downloadCreative(param, (event) => {
            let bytesPerSecond = (event.loaded - lastLoaded) / ((Date.now() - uploadStartTime) / 1000)
            this.bytesPerSecond = Math.floor(bytesPerSecond / 10) / 100 || 0
            //this.uploadPercentage = Math.floor((((i / size) + (event.loaded / event.total / size)) * 100)) || 0
          }).then(res => {
            let filename = window.decodeURI(res.headers['content-disposition'].split('=')[1])
            let blob = new Blob([res.data])
            this.blobToBase64(blob).then(res => {
              let file = this.bToF(res, filename)
              console.log(file)
              this.uploadVideo.uploadFile(file, this, i, idArray[i], this.accessToken, (xhr) => {
                this.uploadXhr = xhr
              })
            })
          }).catch(() => {
            this.youTubeErrorCount++
            this.validYouTubeStatus()
          })
          this.uploadCurrent++
        }
      }
    },
    validYouTubeStatus() {
      this.$emit('validYouTubeStatus', this.youTubeCompleteCount, this.youTubeErrorCount, "无")
      this.creativeCount = 0
      this.youTubeCompleteCount = 0
      this.youTubeErrorCount = 0
    },
    blobToBase64(blob) {
      return new Promise((resolve, reject) => {
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
          resolve(e.target.result);
        };
        // readAsDataURL
        fileReader.readAsDataURL(blob);
        fileReader.onerror = () => {
          reject(new Error('blobToBase64 error'));
        };
      });
    },
    bToF(data, fileName) {
      const dataArr = data.split(",");
      const byteString = atob(dataArr[1]);
      const options = {
        type: "video/mp4",
        endings: "native"
      };
      const u8Arr = new Uint8Array(byteString.length);
      for (let i = 0; i < byteString.length; i++) {
        u8Arr[i] = byteString.charCodeAt(i);
      }
      return new File([u8Arr], fileName, options);
    }
  }
}
</script>

<style scoped>

</style>
